<?php

namespace W3;

use function add_action;

!defined('W3_ROOT_DIR') AND exit;

/**
 * 后台初始化模块
 *
 * @author edikud
 * @date 2022/10/22
 * @copyright Copyright (c) 2022 W3 (http://www.mcooo.com)
 * @license GNU General Public License 2.0
 */

class Admin extends Widget
{
    /**
     * 菜单栏目
     * @var []
     */
    public static $menu = [];
	
    /**
     * 菜单面板
     * @var []
     */
    public static $panel = [];
	
    /**
     * 初始化
     *
     * @access protected
     * @return void
     */
    protected function init()
    {
		# 定义变量默认数据
        $this->parameter([
			
			# 设置主体
			'main' => 'admin.init',	
			
		], true);

		# 路由规则列表
		Router::map([
			
		    ['admin.general /admin/general', 'Module\Admin\General', 'action', 'index'], 
			['admin.reading /admin/reading', 'Module\Admin\Reading', 'action', 'index'], 
			['admin.discussion /admin/discussion', 'Module\Admin\Discussion', 'action', 'index'], 
			['admin.profile /admin/profile', 'Module\Admin\Profile', 'action', 'index'], 
			['admin.password /admin/password', 'Module\Admin\Password', 'action', 'index'], 
			['admin.permalink /admin/permalink/?{action:\w*}', 'Module\Admin\Permalink', 'action', 'index'], 
			['admin.plugin /admin/plugin/?{action:\w*}', 'Module\Admin\Plugin', 'action', 'index'], 
			['admin.theme /admin/theme/?{action:\w*}', 'Module\Admin\Theme', 'action', 'index'], 
			['admin.user /admin/user/?{action:\w*}', 'Module\Admin\User', 'action', 'index'], 
			['admin.comment /admin/comment/?{action:\w*}', 'Module\Admin\Comment', 'action', 'index'], 
			['admin.page /admin/page/?{action:\w*}', 'Module\Admin\Page', 'action', 'index'], 
			['admin.post /admin/post/?{action:\w*}', 'Module\Admin\Post', 'action', 'index'], 
			['admin.category /admin/category/?{action:\w*}', 'Module\Admin\Category', 'action', 'index'], 
			['admin.tag /admin/tag/?{action:\w*}', 'Module\Admin\Tag', 'action', 'index'],
			
	    ]);
			
		# 默认的后台404响应
		Error::error404(function ($msg = NULL){
				
			Start::notFound($this, $msg);
		});

		# 父节点数据
        self::$menu = [
		    'board'=>['name'=>__('控制台'), 'icon'=>'<svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6H8C6.89543 6 6 6.89543 6 8V18C6 19.1046 6.89543 20 8 20H18C19.1046 20 20 19.1046 20 18V8C20 6.89543 19.1046 6 18 6Z" fill="none" stroke="currentColor" stroke-width="4" stroke-linejoin="round"/><path d="M18 28H8C6.89543 28 6 28.8954 6 30V40C6 41.1046 6.89543 42 8 42H18C19.1046 42 20 41.1046 20 40V30C20 28.8954 19.1046 28 18 28Z" fill="none" stroke="currentColor" stroke-width="4" stroke-linejoin="round"/><path d="M35 20C38.866 20 42 16.866 42 13C42 9.13401 38.866 6 35 6C31.134 6 28 9.13401 28 13C28 16.866 31.134 20 35 20Z" fill="none" stroke="currentColor" stroke-width="4" stroke-linejoin="round"/><path d="M40 28H30C28.8954 28 28 28.8954 28 30V40C28 41.1046 28.8954 42 30 42H40C41.1046 42 42 41.1046 42 40V30C42 28.8954 41.1046 28 40 28Z" fill="none" stroke="currentColor" stroke-width="4" stroke-linejoin="round"/></svg>', 'priority'=>20],
			
		    'setting'=>['name'=>__('设置'), 'icon'=>'<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-settings"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>', 'priority'=>40],
			
			'manage'=>['name'=>__('管理'), 'icon'=>'<svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="4" y="6" width="40" height="36" rx="3" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M4 14H44" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M20 24H36" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M20 32H36" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 24H14" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 32H14" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>', 'priority'=>60]
		];

		# 子节点数据
        self::$panel =  [
		    'board'=>[
                [__('首页'), __('后台首页'), $this->adminUrl(false), 'member'],
                [__('插件'), __('插件管理'), $this->adminUrl('plugin', false), 'admin'],
                [NULL, NULL, $this->adminUrl('plugin/config', false), 'admin', true],
                [__('外观'), __('网站外观'), $this->adminUrl('theme', false), 'admin'],
                [NULL, NULL, $this->adminUrl('theme/edit', false), 'admin', true],
                [__('配置外观'), __('配置外观'), $this->adminUrl('theme/config', false), 'admin', true]		
		    ],
		    'setting'=>[	
                [__('基本'), __('基本设置'), $this->adminUrl('general', false), 'admin'],
                [__('评论'), __('评论设置'), $this->adminUrl('discussion', false), 'admin'],
                [__('阅读'), __('阅读设置'), $this->adminUrl('reading', false), 'admin'],
                [__('永久链接'), __('永久链接设置'), $this->adminUrl('permalink', false), 'admin'],
                [__('个人资料'), __('个人资料设置'), $this->adminUrl('profile', false), 'member'],
                [__('密码'), __('密码修改'), $this->adminUrl('password', false), 'member']	
		    ],
		    'manage'=>[
                [__('文章'), __('管理文章'), $this->adminUrl('post', false), 'contributor', false, $this->adminUrl('post/add', false)],
				[NULL, NULL, $this->adminUrl('post/add', false), 'contributor', true],
                [NULL, NULL, $this->adminUrl('post/edit', false), 'contributor', true, $this->adminUrl('post/add', false)],
				
                [__('独立页面'), __('管理独立页面'), $this->adminUrl('page', false), 'editor', false, $this->adminUrl('page/add', false)],
				[NULL, NULL, $this->adminUrl('page/add', false), 'editor', true],
                [NULL, NULL, $this->adminUrl('page/edit', false), 'editor', true, $this->adminUrl('page/add', false)],
				
                [__('评论'), __('管理评论'), $this->adminUrl('comment', false), 'contributor'],
                [__('分类'), __('管理分类'), $this->adminUrl('category', false), 'editor', false, $this->adminUrl('category/add', false)],
			    [NULL, NULL, $this->adminUrl('category/add', false), 'admin', true],
                [NULL, NULL, $this->adminUrl('category/edit', false), 'admin', true, $this->adminUrl('category/add', false)],
                [__('标签'), __('管理标签'), $this->adminUrl('tag', false), 'editor', false, $this->adminUrl('tag/add', false)],
				[NULL, NULL, $this->adminUrl('tag/add', false), 'editor', true],
                [NULL, NULL, $this->adminUrl('tag/edit', false), 'editor', true, $this->adminUrl('tag/add', false)],			
                [__('用户'), __('管理用户'), $this->adminUrl('user', false), 'admin', false, $this->adminUrl('user/add', false)],
			    [NULL, NULL, $this->adminUrl('user/add', false), 'admin', true],
                [NULL, NULL, $this->adminUrl('user/edit', false), 'admin', true, $this->adminUrl('user/add', false)],
		    ]
		];
		
		# 加载jquery
		add_script('jquery', $this->assetUrl('js/jquery-1.10.2.min.js', false), true);
		
		# 加载cookie
		add_script('cookie', $this->assetUrl('js/jquery.cookie.js', false), ['jquery'], true);
		
		# 加载common
		add_script('common', $this->assetUrl('js/common.js', false), ['jquery'], true);
	
        add_action( 'admin_header' , function () 
		{
		    echo Asset::styles();
		    echo Asset::scripts();
        });

        add_action( 'admin_footer' , function () 
		{  
		    echo Asset::scripts(true);
        });
		
		$start = Admin::class;
        add_action( 'call@tabs',        [$start, '_tabs']);
        add_action( 'call@view',        [$start, '_view']);
        add_action( 'call@menu',        [$start, '_menu']);	
        add_action( 'call@operate',     [$start, '_operate']);
        add_action( 'call@header',      [$start, '_header']);
        add_action( 'call@footer',      [$start, '_footer']);
        add_action( 'call@addMenu',     [$start, '_addMenu']);	
        add_action( 'call@removeMenu',  [$start, '_removeMenu']);
        add_action( 'call@addPanel',    [$start, '_addPanel']);
        add_action( 'call@removePanel', [$start, '_removePanel']);
		
        add_action( ['admin.post', 'admin.page'], function($widget){

			if (in_array($widget->request->action, ['edit', 'add'])) {
				
				$id = $widget->request->filter('int')->cid;
				$type = str_replace('admin.', '', $widget->parameter->main);
                $js = self::_uploadScript($widget, $type, $id);
					
                /** 默认上传script (可覆盖或删除) */
		        add_script($type . '-pic-upload', $js, ['jquery', 'common'], true);
		    }
		});
		
        add_action( 'admin.category', function($widget){

			if (in_array($widget->request->action, ['edit', 'add'])) {
				
				$id = $widget->request->filter('int')->mid;
                $js = self::_uploadScript($widget, 'category', $id);
					
                /** 默认上传script (可覆盖或删除) */
		        add_script('category-pic-upload', $js, ['jquery', 'common'], true);
		    }
		});
		
        add_action( 'admin.user', function($widget){

			if (in_array($widget->request->action, ['edit', 'add'])) {
				
				$id = $widget->request->filter('int')->uid;
                $js = self::_uploadScript($widget, 'user', $id);
					
                /** 默认上传script (可覆盖或删除) */
		        add_script('user-pic-upload', $js, ['jquery', 'common'], true);
		    }
		});
    }
	
    public function execute()
    {
		$this->auth->check('member');
		
		Token::set($this->config->secret . '&' . $this->auth->uid);
	}

    public static function _uploadScript(Widget $widget, $type, $id)
    {
		$uploadUrl = $widget->uploadUrl(false);
		$cdnUrl = $widget->cdnUrl(false);
		$uploading = __('正在上传...');
		$upload = __('上传');
		
        $js = <<<EOF
$(document).ready(function () {
    var jform = $("form");					
    jform.on('change', 'input[type="file"]', function(e) {
	var jthis = $(this);
	var jdiv = jthis.parent().parent().parent();
	var jinput = jdiv.find('input[name="pic"]');

    $.ajax({
		url: '$uploadUrl',
        files: jthis,
        iframe: true,
		data: {type: '$type', id:'$id'},
		processData: false,
		dataType: 'text',
		cache:false,
		beforeSend: function(s){
			jdiv.find('.w3-upload span').html('$uploading');
		},
		success: function(s){
		    s = (new Function("return " + s))(); 
		    if(typeof s != 'false') {
					if(!$('img', jdiv).length){
						jdiv.find('.form-description').after('<img style="margin: 5px 0;" class="w3-pic" src="$cdnUrl' + s.path+'?'+Math.random() + '"/>');
						
					}else{
						$('img', jdiv).attr('src', '$cdnUrl' + s.path+'?'+Math.random());
					}
					jinput.val(s.path);

		    } else {
			    $.alert(s);
		    }
		},
		complete: function(s){
			jdiv.find('.w3-upload span').html('$upload');
		},
        });
    });			

});
EOF;

    return $js;
	}

    /**
     * 输出视图
     *
     * @param mixed $widget	 所属调用的组件
     * @return mixed
     */
    public static function _view(Widget $widget)
    {
		static $initialized = false;
		
		# 防止嵌套调用, 发生死循环
		if ($initialized){
				
			throw new Exception('禁止嵌套调用', 403);
			
			return ;
	    }
			
		$initialized = true;

		# 初始化Menu
		$widget->menu();
		
		$widget->require(W3_ROOT_DIR . 'system/static/html/admin.php');
	}

    /**
     * 输出导航
     *
     * @param mixed $widget	 所属调用的组件
     * @return mixed
     */
    public static function _menu(Widget $widget): Widget
    {
        return $widget->widget('W3\Menu', !$widget->exists('W3\Menu') ? [
			'parentNodes'=>Admin::$menu,
		    'childNodes'=>Admin::$panel,
			'baseUrl'=>rtrim($widget->adminUrl(false), '/'),
			'widget'=>$widget
		] : NULL);
	}

    /**
     * 输出操作按钮
     *
     * @param mixed $widget	 所属调用的组件
	 * @param boolean $return 是否返回
     * @return mixed
     */
    public static function _operate(Widget $widget, bool $echo = true)
    {
		static $once = 0;
		
        $operate = $widget->parameter->operate;
		$result = '<div class="w3-operate">';

        foreach ($operate as $key => $button) 
		{
			$button['href'] = $button['href'] ?? 'javascript:;';
			$button['data-name'] = $key;
			$name = $button['name'] ?? '';
			unset($button['name']);

			$result .= Html::a(NULL, $name)->addClass('btn btn-outline-primary')->attributes($button)->render();
        }
		
		$result .= '</div>';

		!$once && add_script('tableSelect', "
    $(document).ready(function(){
        $('.table-responsive').tableSelect({
            checkEl     :   'input[type=checkbox]',
            rowEl       :   'tbody tr',
            actionEl    :   '.w3-operate a'
        });

    });", ['jquery', 'common'], true);
				
		$once = 1;

        if ($echo) {
            echo $result;
        } else {
            return $result;
        }
	}

    /**
     * 输出操作按钮
     *
     * @param mixed $widget	 所属调用的组件
	 * @param boolean $return 是否返回
     * @return mixed
     */
    public static function _tabs(Widget $widget, bool $echo = true)
    {
        $tabs = $widget->parameter->tabs;
		$result = '<div class="w3-tabs mb-1">';

        foreach ($tabs as $key => $button) 
		{
			$current = $balloon = false;
			$hide = $button['hide'] ?? false;
			unset($button['hide']);

			if(isset($button['current'])){
				
				$current = call_user_func($button['current'], $widget);
				unset($button['current']);
			}

			if(isset($button['balloon'])){
				
				# 
				!$hide && $balloon = call_user_func($button['balloon'], $widget);
				unset($button['balloon']);
			}

			$button['href'] = $button['href'] ?? 'javascript:;';
			$button['data-name'] = $key;
			$name = $button['name'] ?? '';
			unset($button['name']);

			$button = Html::a(NULL, $name)->addClass('btn btn-light')->attributes($button);
			$current && $button->removeClass('btn-light')->addClass('btn-primary-soft');
			$balloon && $button->set('<span class="balloon">' . $balloon . '</span>');
			$hide && $button->hide();
			
			$result .= $button->render();
        }
		
		$result .= '</div>';

        if ($echo) {
            echo $result;
        } else {
            return $result;
        }
	}


    /**
     * 输出header
     *
     * @param mixed $widget	 所属调用的组件
     * @return void
     */
    public static function _header(Widget $widget, $rule = NULL)
    {
	    $keywords     = $widget->parameter->keywords;
	    $description  = $widget->parameter->description;
	
        $header = [];
        $allows = [
            'description'   =>  htmlspecialchars($description),
            'keywords'      =>  htmlspecialchars($keywords),
        ];

        if (!empty($rule)) {
            parse_str($rule, $rules);
            $allows = array_merge($allows, $rules);
        }

        if (!empty($allows['description'])) {
            $header[] = '<meta name="description" content="' . $allows['description'] . '" />';
        }

        if (!empty($allows['keywords'])) {
            $header[] = '<meta name="keywords" content="' . $allows['keywords'] . '" />';
        }

        /** 输出header */
        echo implode("\n", array_filter($header));
		
        /** 插件接口 */
		\do_action('admin_header', $widget);
	}
	
    /**
     * 输出footer
     *
     * @param mixed $widget	 所属调用的组件
     * @return mixed
     */
    public static function _footer(Widget $widget)
    {
		/** 插件接口 */
        \do_action('admin_footer', $widget);
	}

    /**
     * 增加一个菜单
     *
     * @access public
     * @param mixed $widget	 所属调用的组件
     * @param string $index 菜单索引
     * @param string $name 菜单标题
     * @param string $icon 菜单icon
     * @return void
     */
    public static function _addMenu(Widget $widget, string $index, string $name, string $icon, int $priority = 99)
    {
		Admin::$menu[$index] = ['name'=>$name, 'icon'=>$icon, 'priority'=>$priority];
	}

    /**
     * 移除一个菜单
     *
     * @param mixed $widget	 所属调用的组件
     * @param string $index 菜单索引
     * @return mixed
     */
    public static function _removeMenu(Widget $widget, string $index)
    {
        if (isset(Admin::$menu[$index])) {
            unset(Admin::$menu[$index]);
        }
	}

    /**
     * 增加一个面板
     *
     * @access public
     * @param mixed $widget	 所属调用的组件
     * @param integer $index 菜单索引
     * @param string $title 面板标题
     * @param string $subTitle 面板副标题
     * @param string $url 项目链接
     * @param string $access 进入权限
     * @param boolean $hidden 是否隐藏
     * @param string $addLink 新增项目链接, 会显示在页面标题之后
     * @return void
     */
    public static function _addPanel(Widget $widget, string $index, string $title, string $subTitle, string $url, string $access, bool $hidden = false, string $addLink = '')
    {
        Admin::$panel[$index][] = [$title, $subTitle, $url, $access, $hidden, $addLink];
	}

    /**
     * 移除一个面板
     *
     * @param mixed $widget	 所属调用的组件
     * @param string $index 菜单索引
     * @param string $url 项目链接
     * @return mixed
     */
    public static function _removePanel(Widget $widget, string $index, string $url)
    {
        empty(Admin::$panel[$index]) && Admin::$panel[$index] = [];
        foreach (Admin::$panel[$index] as $key => $val) 
		{
            if ($val[2] == $url) {
                unset(Admin::$panel[$index][$key]);
            }
        }
	}

}

